
import time
import requests
import threading
import json
import subprocess
import paho.mqtt.client as mqtt
from operation_flow import OperationFlow
from util import get_mac_address, send_mqtt_message, set_cabinet_current_order_status, upload_mp4_file
import redis
import logging
import os
from abnormal import Abnormal
from setting import *
from inventory import Inventory

logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')

logger = logging.getLogger(__name__)


class MQTTClient:

    def __init__(self, broker_address, broker_port, client_name):
        self.client = mqtt.Client(client_name)
        self.broker_address = broker_address
        self.broker_port = broker_port
        
        # 设置连接成功和消息接收的回调函数
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message

        # 创建一个新的线程对象
        self.heartbeat_thread = threading.Thread(target=self.send_heartbeat)

        self.r = redis.Redis(host='localhost', port=6379, db=0)

    # 连接成功的回调函数
    def on_connect(self, client, userdata, flags, rc):
        print("Connected with result code " + str(rc))

        mac = get_mac_address()

        topic = "rfid_cabinet/rx/{}".format(mac)
        # 订阅MQTT Topic
        self.client.subscribe(topic)

        logger.info("订阅MQTT Topic: {}".format(topic))

        
    # 接收MQTT消息的回调函数
    def on_message(self, client, userdata, msg):

        per_msg = json.loads(msg.payload.decode())

        logger.info("MQTT接收信息：{}  {}".format(msg.topic, per_msg))

        if per_msg.get("task_type") == "开门":

            if per_msg["task_data"]["orderid"].startswith("bh"):

                set_cabinet_current_order_status("补货")
            else:

                set_cabinet_current_order_status("购物")


            with OperationFlow(per_msg["task_data"]["orderid"]) as o:

                logger.info("开启业务流程")

        if per_msg.get("task_type") == "提交盘点信息": # 这里有个大BUG TODO

            current_order_status = self.r.get(CABINET_CURRENT_ORDER_STATUS) 

            logger.info("current_order_status:{}".format(current_order_status.decode()))

            if current_order_status == None or current_order_status.decode() == '无任务':

                self.send_now_esp_set_to_mqtt()

        if per_msg.get("task_type") == "重新盘点":

            with Inventory(task_number=per_msg["task_data"]["orderid"]) as inv:

                inv.flow()

        if per_msg.get("task_type") == "restart_auto_ssh":

            pppd_service_cmd = ["systemctl", "restart", "auto-ssh"]

            subprocess.Popen(pppd_service_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

        if per_msg.get("task_type") == "设置广告":

            ad_media_url = per_msg["task_data"]["ad_media_url"]

            ad_volume = per_msg["task_data"].get("ad_volume")

            if ad_volume:

                self.r.set(AD_VOLUME, float(ad_volume))

            ad_name = os.path.basename(ad_media_url)

            file_path = "/home/linaro/Videos/{}".format(ad_name)

            with open("/home/linaro/Videos/.play_ad_file", 'w') as f:

                f.write(file_path)

            # if not os.path.exists(file_path):

            #     response = requests.get(ad_media_url)

            #     if response.status_code == 200:

            #         with open(file_path, 'wb') as file:

            #             file.write(response.content)

            #         logger.info("视频文件下载成功")
            #     else:
            #         logger.info("视频文件下载失败，错误码：", response.status_code)


        if per_msg.get("task_type") == "上传购物视频":

            orderid = per_msg["task_data"]["orderid"]

            video_file_path = "/media/{}.mp4".format(orderid)

            logger.info("上传视频：{}".format(video_file_path))

            res = upload_mp4_file(video_file_path)

            if res == "视频文件不存在!":

                logger.error(res)

            else:

                logger.info(res)

        if per_msg.get("task_type") == "设置广告音量":

            volume = per_msg["task_data"]["ad_volume"]

            self.r.set(AD_VOLUME, float(volume))

            cmd = ["systemctl", "restart", "ad_media"]

            subprocess.run(cmd)

            logger.info("设置广告音量：{}：并重启广告服务".format(volume))

        
        if per_msg.get("task_type") == "设置背景颜色":

            # top_color = per_msg["task_data"]["top_color"]
            # mid_color = per_msg["task_data"]["mid_color"]

            with open("/home/linaro/.ui_args.json", "w", encoding="utf-8") as f:

                f.write(json.dumps(per_msg["task_data"]))

            cmd = ["systemctl", "restart", "inventory_ui"]

            subprocess.run(cmd)

            logger.info("设置背景颜色{}：并重启服务")

            

        

            

    def send_now_esp_set_to_mqtt(self):

        '''发送now_esp_set到数据中心'''

        now_esp_set = self.r.smembers("now_esp_set")

        now_esp_list = [item.decode() for item in now_esp_set]

        msg = {
            "mac": get_mac_address(),
            "esp_list": now_esp_list
        }

        send_mqtt_message(message=json.dumps(msg), topic="rfid_cabinet/esp_list")

        return now_esp_list
    
    # 发送心跳数据的方法
    def send_heartbeat(self):
        while True:

            mac = get_mac_address()

            cabinet_current_status = self.r.get("cabinet_current_status")

            if cabinet_current_status:

                cabinet_current_status = cabinet_current_status.decode()

            try:

                data = {"mac": mac, "cabinet_current_status": cabinet_current_status, "cabinet_abnormal": Abnormal().abnormal()}

            except Exception as e:

                logger.error(str(e))

            else:

                logger.info("heartbeat_info: {}".format(data))

                # 发布心跳数据到 MQTT Topic
                self.publish_message("rfid_cabinet/cabinet_heartbeat",  json.dumps(data))
                # 暂停10秒
                time.sleep(10)


    # 连接MQTT Broker
    def connect(self):

        self.client.connect(self.broker_address, self.broker_port, 60)

        # 启动心跳线程
        self.heartbeat_thread.start()

        logger.info("启动心跳线程")

        self.client.loop_forever()

    # 发布消息到MQTT Topic
    def publish_message(self, topic, message):
        self.client.publish(topic, message)


def run_mqtt_client():
    
    mqtt_client = MQTTClient(broker_address="47.96.3.242", broker_port=1883, client_name="cabinet-{}".format(get_mac_address()))

    mqtt_client.connect()



if __name__ == "__main__":


    run_mqtt_client()